﻿using System;
using System.Text;
using System.Data;
//using MySql.Data.MySqlClient;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json.Linq;
using T.FAS.Runtime.DataModel.Dao;
using T.FAS.Runtime.Metadata.Entity.DataModel;
using T.FAS.Runtime.Metadata.Entity;
using Const = T.FAS.Runtime.DataModel.Plugin.MetaManagerConst;
using DataColumn = T.FAS.Runtime.Metadata.Entity.DataModel.DataColumn;
using T.FAS.Runtime.Base.Entity;
using System.Data.SqlClient;
using T.FAS.Runtime.Base.Common;

namespace T.FAS.Runtime.DataModel.Plugin
{
    /// <summary>
    /// DataObject MySQL Builder
    /// </summary>
    public class DataObjectMySQLBuilder : DataObjectSQLBuilderBase, IMetaBusinessSQLBuilder
    {
        protected override DatabaseType DatabaseType => DatabaseType.MySQL;
        private IList<DataObject> contents = new List<DataObject>();

        /// <summary>
        /// 待生成SQL的元数据集合（DO SDO)
        /// </summary>
        public override IList<IMetaDataContent> Contents
        {
            get
            {
                return contents.Select(o => (IMetaDataContent)o).ToList();
            }
            set
            {
                contents?.Clear();
                contents = value.Select(o => (DataObject)o).ToList();
            }
        }

        #region Private Funcs 
        /// <summary>
        /// 生成Drop Column SQL
        /// </summary>
        /// <param name="dataObject">旧的DO，方便拿到删除列的列名</param>
        /// <param name="columns"></param>
        /// <returns></returns>
        private List<SQLItem> GetColumnDropSQL(DataObject dataObject, List<DataColumn> columns)
        {
            var template = GetTemplate(dataObject);
            //删除column SQL Item
            List<SQLItem> dropColumns = new List<SQLItem>();
            foreach (var column in columns)
            {
                SQLItem item = template.Clone();
                string DropColSQL = Const.MySQL.ColumnDrop.Format(
                    new Dictionary<string, object>
                    {
                        {Const.table_name, ProcessCaseString(dataObject.LogicTableName) },
                        {Const.column_name, ProcessCaseString(column.ColumnName) },
                    });
                item.SQL += DropColSQL;
                dropColumns.Add(item);
            }
            return dropColumns;
        }

        /// <summary>
        /// 生成Modify Column SQL
        /// </summary>
        /// <param name="dataObject"></param>
        /// <param name="columns"></param>
        /// <returns></returns>
        protected override List<SQLItem> GetColumnModifySQL(DataObject dataObject, List<ModifyColumnInfo> columns)
        {
            //修改column SQL Item
            var template = GetTemplate(dataObject);
            List<SQLItem> modifyColumnsSQLs = new List<SQLItem>();
            foreach (var modifyColInfo in columns)
            {
                SQLItem modifyColItem = template.Clone();
                //如果默认值发生改动, 不需要特殊处理
                string databaseDataType = DataTypeTool.GetMappingDataType(template.DatabaseType, modifyColInfo.NewColumn, contents);
                //非只包含国际化变更、中文存储变更时，生成modify语句
                if (modifyColInfo.ChangeTypeLayer != (int)ChangeType.IsInternational
                    && modifyColInfo.ChangeTypeLayer != (int)ChangeType.Unicode)
                {
                    string modifyColSQL = Const.MySQL.ColumnModify.Format(
                    new Dictionary<string, object>
                    {
                        { Const.table_name, ProcessCaseString(dataObject.LogicTableName) },
                        { Const.column_name, ProcessCaseString(modifyColInfo.NewColumn.ColumnName) },
                        { Const.data_type, databaseDataType},
                        { Const.nullable, modifyColInfo.NewColumn.IsNullable ? " NULL ": " NOT NULL " },
                        { Const.@default, DealWithDefault(modifyColInfo.NewColumn) },
                        { Const.comment, DealWithComment(modifyColInfo.NewColumn)},
                    });
                    modifyColItem.SQL += modifyColSQL;
                    modifyColumnsSQLs.Add(modifyColItem);
                }
                //当列设置为国际化时，需要额外生成Add Column 语句
                bool isInternationalChanged = (modifyColInfo.ChangeTypeLayer & (int)ChangeType.IsInternational) == (int)ChangeType.IsInternational;
                if (isInternationalChanged && modifyColInfo.NewColumn.IsInternational)
                {
                    var internationalSQLs = GetInternalColumnAddSQLs(dataObject, databaseDataType, modifyColInfo.NewColumn);
                    if (internationalSQLs != null && internationalSQLs.Count > 0)
                    {
                        foreach (var internationalSQL in internationalSQLs)
                        {
                            SQLItem internationalSQLItem = template.Clone();
                            internationalSQLItem.SQL = internationalSQL;
                            modifyColumnsSQLs.Add(internationalSQLItem);
                        }
                    }
                }

                //当列设置为掩码时，需要额外生成Add Column 语句
                bool isMaskingChanged = (modifyColInfo.ChangeTypeLayer & (int)ChangeType.MaskSetting) == (int)ChangeType.MaskSetting;
                if (isMaskingChanged && modifyColInfo.NewColumn.MaskingRule.IsEnable && ConfigUtil.Instance.EnableFASMaskStorage)
                {
                    var maskingSQLs = GetMaskingColumnAddSQLs(dataObject, databaseDataType, modifyColInfo.NewColumn);
                    if (maskingSQLs != null && maskingSQLs.Count > 0)
                    {
                        foreach (var maskingSQL in maskingSQLs)
                        {
                            SQLItem MaskingSQLItem = template.Clone();
                            MaskingSQLItem.SQL = maskingSQL;
                            modifyColumnsSQLs.Add(MaskingSQLItem);
                        }
                    }
                }
            }
            return modifyColumnsSQLs;
        }
        #endregion
    }
}
